home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / misc / emu / ATUtilities.lha / ATUtilities / ASM / RDISK.ASM < prev    next >
Assembly Source File  |  2000-09-26  |  23KB  |  372 lines

  1. ;**********************************************************************;
  2. ;*                            R A M D I S K                           *;
  3. ;*--------------------------------------------------------------------*;
  4. ;*    Aufgabe        : Dieses Programm ist ein Treiber fr eine 160KB *;
  5. ;*                     RAM-Disk.                                      *;
  6. ;*--------------------------------------------------------------------*;
  7. ;*    Autor          : MICHAEL TISCHER                                *;
  8. ;*    entwickelt am  :  4.08.1987                                     *;
  9. ;*    letztes Update :  2.11.1991                                     *;
  10. ;*--------------------------------------------------------------------*;
  11. ;*    assemblieren   : MASM RAMDISK;                                  *;
  12. ;*                     LINK RAMDISK;                                  *;
  13. ;*                     EXE2BIN RAMDISK RAMDISK.SYS    oder            *;
  14. ;                                                                     *;
  15. ;*                     TASM RAMDISK                                   *;
  16. ;*                     LINK RAMDISK;                                  *;
  17. ;*                     EXE2BIN RAMDISK RAMDISK.SYS                    *;
  18. ;*--------------------------------------------------------------------*;
  19. ;*    Aufruf         : In das Hauptverzeichnis kopieren, den Befehl   *;
  20. ;*                     DEVICE=RAMDISK.SYS in die Datei CONFIG.SYS     *;
  21. ;*                     aufnehmen und dann System booten.              *;
  22. ;**********************************************************************;
  23.                                                                         
  24. code     segment
  25.                                                                         
  26.          assume cs:code,ds:code,es:code,ss:code
  27.                                                                         
  28.          org 0                   ;Programm hat keinen PSP daher Anfang
  29.                                  ;an der Offsetadresse 0
  30.                                                                         
  31. ;== Konstanten =========================================================
  32.                                                                         
  33. befehl   equ 2                   ;Offset Befehls-Feld im Datenblock
  34. status   equ 3                   ;Offset Status-Feld im Datenblock
  35. anz_ger  equ 13                  ;Offset Anzahl untersttzter Ger„te
  36. wechsel  equ 14                  ;Offset Medium gewechselt?
  37. end_adr  equ 14                  ;Offset Treiber End-Adr. im Datenblock
  38. p_adr    equ 14                  ;Offset Puffer-Adresse im Datenblock
  39. anz_bef  equ 16                  ;die Funktionen 0-16 werden untersttzt
  40. anzahl   equ 18                  ;Offset Anzahl im Datenblock
  41. bpb_adr  equ 18                  ;Offset Adresse des BPB des Medium
  42. sektor   equ 26                  ;Offset erste Sektornummer
  43. ger_bez  equ 22                  ;Offset Ger„te-Bezeichnung der RAMDisk
  44.                                                                         
  45. ;== Daten ==============================================================
  46.                                                                         
  47. erst_b   equ this byte           ;dies ist das erste Byte des Treibers
  48.                                                                         
  49. ;-- Kopf des Ger„te-Treibers -------------------------------------------
  50.                                                                         
  51.          dw -1,-1                ;Verbindung zum n„chsten Treiber
  52.          dw 0100100000000000b    ;Treiber Attribut
  53.          dw offset strat         ;Pointer auf Strategie-Routine
  54.          dw offset intr          ;Pointer auf Interrupt-Routine
  55.          db 1                    ;ein Ger„t wird untersttzt
  56.          db 7 dup (0)            ;diese Bytes geben sonst den Namen an
  57.                                                                         
  58. ;-- Sprungtabelle fr die einzelnen Funktionen -------------------------
  59.                                                                         
  60. fkt_tab  dw offset init          ;Funktion  0: Initialisierung
  61.          dw offset med_test      ;Funktion  1: Medium Test
  62.          dw offset get_bpb       ;Funktion  2: Erstelle BPB
  63.          dw offset lesen         ;Funktion  3: direktes Lesen
  64.          dw offset lesen         ;Funktion  4: Lesen
  65.          dw offset dummy         ;Funktion  5: Lesen, im Puffer bleiben
  66.          dw offset dummy         ;Funktion  6: Eingabe-Status
  67.          dw offset dummy         ;Funktion  7: L”sche Eingabe-Puffer
  68.          dw offset schreibe      ;Funktion  8: Schreiben
  69.          dw offset schreibe      ;Funktion  9: Schreiben & Verifizieren
  70.          dw offset dummy         ;Funktion 10: Ausgabe-Status
  71.          dw offset dummy         ;Funktion 11: L”schen Ausgabe-Puffer
  72.          dw offset schreibe      ;Funktion 12: direktes Schreiben
  73.          dw offset dummy         ;Funktion 13: ™ffnen (diese Fkt ab 3.0)
  74.          dw offset dummy         ;Funktion 14: Schlieáen
  75.          dw offset no_rem        ;Funktion 15: wechselbares Medium?
  76.          dw offset schreibe      ;Funktion 16: Ausgabe bis besch„ftigt
  77.                                                                         
  78. db_ptr   dw (?),(?)              ;Adresse des bergebenen Datenblocks
  79. rd_seg   dw (?)                  ;RD_SEG:0000 ist der Anfang der RAMDisk
  80.                                                                         
  81. bpb_ptr  dw offset bpb,(?)       ;Nimmt die Adresse des BPB auf
  82.                                                                         
  83. boot_sek db 3 dup (0)            ;hier befindet sich noramlerweise ein
  84.                                  ;Sprungbefehl zur Boot-Routine
  85.          db "MITI 1.0"           ;Herstellername & Versionsnummer
  86. bpb      dw 512                  ;512 Bytes pro Sektor
  87.          db 1                    ;1 Sektoren pro Cluster
  88.          dw 1                    ;1 reservierter Sektor (Boot-Sektor)
  89.          db 1                    ;1 File-Allocation-Table (FAT)
  90.          dw 64                   ;maximal 64 Eintr„ge im Hauptverz.
  91.          dw 320                  ;insgesamt 320 Sektoren = 160 KB
  92.          db 0FEh                 ;Media Descriptor (1 Seite mit 40
  93.                                  ;Spuren zu je 8 Sektoren)
  94.          dw 1                    ;jede FAT belegt einen Sektor
  95.                                                                         
  96.          ;-- die Boot-Routine entf„llt, da man ein System nicht ------
  97.          ;-- von einer RAM-Disk booten kann
  98.                                                                         
  99. vol_name db "RAMDISK    "        ;der eigentliche Volume-Name
  100.          db 8                    ;Attribut, definiert Volume-Name
  101.                                                                         
  102. ;== Routinen und Funktionen des Treibers ===============================
  103.                                                                         
  104. strat    proc far                ;Strategie-Routine
  105.                                                                         
  106.          mov  cs:db_ptr,bx       ;Adresse des Datenblocks in der
  107.          mov  cs:db_ptr+2,es     ;Variable DB_PTR merken
  108.                                                                         
  109.          ret                     ;zurck zum Aufrufer
  110.                                                                         
  111. strat    endp
  112.                                                                         
  113. ;-----------------------------------------------------------------------
  114.                                                                         
  115. intr     proc far                ;Interrupt-Routine
  116.                                                                         
  117.          push ax                 ;Register auf Stack sichern
  118.          push bx
  119.          push cx
  120.          push dx
  121.          push di
  122.          push si
  123.          push bp
  124.          push ds
  125.          push es
  126.          pushf                   ;auch das Flag-Register merken
  127.                                                                         
  128.          push cs                 ;Datensegment-Register setzen
  129.          pop  ds                 ;Code ist hier mit Daten identisch
  130.                                                                         
  131.          les  di,dword ptr db_ptr;Adresse des Datenblock nach ES:DI
  132.          mov  bl,es:[di+befehl]  ;Befehls-Code holen
  133.          cmp  bl,anz_bef         ;ist Befehls-Code erlaubt?
  134.          jle  bc_ok              ;JA --> bc_ok
  135.                                                                         
  136.          mov  ax,8003h           ;Code fr "unbekannter Befehl"
  137.          jmp  short intr_end     ;zurck zum Aufrufer
  138.                                                                         
  139.          ;-- Befehls-Code war o.k. --> Befehl ausfhren ----------------
  140.                                                                         
  141. bc_ok:   shl  bl,1               ;Pointer in Sprungtabelle errechnen
  142.          xor  bh,bh              ;BH l”schen
  143.          call [fkt_tab+bx]       ;Funktion aufrufen
  144.                                                                         
  145.          ;-- Ausfhrung der Funktion beendet ---------------------------
  146.                                                                         
  147. intr_end label near
  148.          push cs                 ;Datensegment-Register setzen
  149.          pop  ds                 ;Code ist hier mit Daten identisch
  150.                                                                         
  151.          les  di,dword ptr db_ptr;Adresse des Datenblock nach ES:DI
  152.          or   ax,0100h           ;Fertig-Bit setzen
  153.          mov  es:[di+status],ax  ;das ganze im Status-Feld abspeichern
  154.                                                                         
  155.          popf                    ;Flag-Register zurckholen
  156.          pop  es                 ;andere Register zurckholen
  157.          pop  ds
  158.          pop  bp
  159.          pop  si
  160.          pop  di
  161.          pop  dx
  162.          pop  cx
  163.          pop  bx
  164.          pop  ax
  165.                                                                         
  166.          ret                     ;zurck zum Aufrufer
  167.                                                                         
  168. intr     endp
  169.                                                                         
  170. ;-----------------------------------------------------------------------
  171.                                                                         
  172. init     proc near               ;Initialisierungs-Routine
  173.                                                                         
  174.          ;-- der folgende Code wird nach der Installation --------------
  175.          ;-- von der eigentlichen RAMDisk berschrieben
  176.                                                                         
  177.          ;-- Ger„tebezeichnung der RAMDisk ermitteln -------------------
  178.                                                                         
  179.          mov  ah,30h             ;DOS Version mit Hilfer der Fkt. 30(h)
  180.          int  21h                ;des DOS-Interrupt 21(h) abfragen
  181.          cmp  al,3               ;ist Version 3 oder h”her?
  182.          jb   prinm              ;JA --> PRINM
  183.                                                                         
  184.          mov  al,es:[di+ger_bez] ;Ger„tebezeichnung holen
  185.          add  al,"A"             ;in Buchstaben umwandeln
  186.          mov  im_ger,al          ;in Installations-Meldung abspeichern
  187.                                                                         
  188. prinm:   mov  dx,offset initm    ;Adresse der Installations-Meldung
  189.          mov  ah,9               ;Funktionsnummer fr String ausgeben
  190.          int  21h                ;DOS-Interrupt aufrufen
  191.                                                                         
  192.          ;-- Adresse des ersten Bytes hinter der RAMDisk berechen ------
  193.          ;-- und als Endadresse des Treibers setzen
  194.                                                                         
  195.          mov  word ptr es:[di+end_adr],offset ramdisk+8000h
  196.          mov  ax,cs                      ;die RAM-Disk ist 32KB plus
  197.          add  ax,2000h                   ;2 * 64KB groá
  198.          mov  es:[di+end_adr+2],ax
  199.          mov  byte ptr es:[di+anz_ger],1          ;1 Ger„t wird unterst.
  200.          mov  word ptr es:[di+bpb_adr],offset bpb_ptr ;Adresse des BPB-
  201.          mov  es:[di+bpb_adr+2],ds                    ;Pointer
  202.                                                                         
  203.          mov  ax,cs              ;Segmentadresse des Beginn der RAMDisk
  204.          mov  bpb_ptr+2,ds       ;Segmentadresse der BPB in BPB-Pointer
  205.          mov  dx,offset ramdisk  ;zur Offsetadresse 0 berechnen
  206.          mov  cl,4               ;Offsetadresse durch 16 teilen und da-
  207.          shr  dx,cl              ;durch in Segmentadresse umrechnen
  208.          add  ax,dx              ;die beiden Segmentadressen addieren
  209.          mov  rd_seg,ax          ;und merken
  210.                                                                         
  211.          ;-- Boot-Sektor anlegen ---------------------------------------
  212.                                                                         
  213.          mov  es,ax              ;Segmentadresse nach ES transferieren
  214.          xor  di,di              ;Boots. beginnt mit dem 1. Byte der RD
  215.          mov  si,offset boot_sek ;Adresse des Boot-Sektor im Speicher
  216.          mov  cx,15              ;nur die ersten 15 Words werden genutzt
  217.          rep  movsw              ;Boot-Sektor in RAMDisk kopieren
  218.                                                                         
  219.          ;-- die FAT anlegen -------------------------------------------
  220.                                                                         
  221.          mov  di,512             ;FAT beginnt mit dem Byte 512 der RD
  222.          mov  al,0FEh            ;Media-Descriptor in das erste Byte der
  223.          stosb                   ;FAT schreiben
  224.          mov  ax,0FFFFH          ;Code fr die Bytes 2 und 3 der FAT
  225.          stosw                   ;in FAT abpspeichern
  226.          mov  cx,236             ;die restlichen 236 Word belegt die FAT
  227.          inc  ax                 ;AX auf 0 setzen
  228.          rep  stosw              ;alle FAT-Eintr„ge auf unbelegt setzen
  229.                                                                         
  230.          ;-- das Hauptverzeichnis mit Volume-Namen anlegen -------------
  231.                                                                         
  232.          mov  di,1024            ;das Hauptverz. beginnt im 3. Sektor
  233.          mov  si,offset vol_name ;Adresse des Volume-Namen im Speicher
  234.          mov  cx,6               ;der Volume-Name ist 6 Words lang
  235.          rep  movsw              ;Volume-Namen in RD kopieren
  236.                                                                         
  237.          mov  cx,1017            ;den Rest des Directories in den Sektoren
  238.          xor  ax,ax              ;2, 3, 4 und 5 mit Nullen fllen
  239.          rep  stosw
  240.                                                                         
  241.          xor  ax,ax              ;alles o.k.
  242.          ret                     ;zurck zum Aufrufer
  243.                                                                         
  244. init     endp
  245.                                                                         
  246. ;-----------------------------------------------------------------------
  247.                                                                         
  248. dummy    proc near               ;diese Routine bewirkt nichts
  249.                                                                         
  250.          xor  ax,ax              ;Besch„ftigt-Bit l”schen
  251.          ret                     ;zurck zum Aufrufer
  252.                                                                         
  253. dummy    endp
  254.                                                                         
  255. ;-----------------------------------------------------------------------
  256.                                                                         
  257. med_test proc near               ;das Medium der RAM-Disk kann nicht ge-
  258.                                  ;wechselt werden
  259.                                                                         
  260.          mov  byte ptr es:[di+wechsel],1
  261.          xor  ax,ax              ;Besch„ftigt-Bit l”schen
  262.          ret                     ;zurck zum Aufrufer
  263.                                                                         
  264. med_test endp
  265.                                                                         
  266. ;-----------------------------------------------------------------------
  267.                                                                         
  268. get_bpb  proc near               ;Adresse des BPB an DOS bergeben
  269.                                                                         
  270.          mov  word ptr es:[di+bpb_adr],offset bpb
  271.          mov  word ptr es:[di+bpb_adr+2],ds
  272.                                                                         
  273.          xor  ax,ax              ;Besch„ftigt-Bit l”schen
  274.          ret                     ;zurck zum Aufrufer
  275.                                                                         
  276. get_bpb  endp
  277.                                                                         
  278. ;-----------------------------------------------------------------------
  279.                                                                         
  280. no_rem   proc near               ;eine RAMDisk kann nicht gewechselt
  281.                                  ;werden
  282.                                                                         
  283.          mov  ax,20              ;Besch„ftigt-Bit setzen
  284.          ret                     ;zurck zum Aufrufer
  285.                                                                         
  286. no_rem   endp
  287.                                                                         
  288. ;-----------------------------------------------------------------------
  289.                                                                         
  290. schreibe proc near
  291.                                                                         
  292.          xor  bp,bp              ;šbertragung DOS --> RAMDisk
  293.          jmp  short move         ;Daten kopieren
  294.                                                                         
  295. schreibe endp
  296.                                                                         
  297. ;-----------------------------------------------------------------------
  298.                                                                         
  299. lesen    proc near
  300.                                                                         
  301.          mov  bp,1               ;šbertragung RAMDisk --> DOS
  302.                                                                         
  303. lesen    endp
  304.                                                                         
  305. ;-- MOVE: eine bestimmte Anzahl Sektoren zwischen RD und DOS verschieben
  306. ;-- Eingabe  : BP = 0 : vom DOS zur RD bertragen (schreiben)
  307. ;--                 1 : von RD zum DOS bertragen (lesen)
  308. ;-- Ausgabe  : keine
  309. ;-- Register : AX, BX, CX, DX, SI, DI, ES, DS und FLAGS werden ver„ndert
  310. ;-- Info     : die ben”tigten Informationen (Anzahl, erster Sektor)
  311. ;--            entnimmt diese Funktion dem vom DOS bergebenen Datenbl.
  312.                                                                         
  313. move     proc near
  314.                                                                         
  315.          mov  bx,es:[di+anzahl]  ;Anzahl der Sektoren lesen
  316.          mov  dx,es:[di+sektor]  ;Nummer des ersten Sektors
  317.          les  di,es:[di+p_adr]   ;Adresse des Puffers nach ES:DI
  318.                                                                         
  319. move_1:  or   bx,bx              ;noch Sektoren lesen?
  320.          je   move_e             ;kein Sektor mehr --> ENDE
  321.          mov  ax,dx              ;Sektornummer nach AX
  322.          mov  cl,5               ;Anzahl der Paragraphen (Segmentein-
  323.          shl  ax,cl              ;heiten) durch Multiplikation mit 32
  324.                                  ;berechnen
  325.          add  ax,cs:rd_seg       ;und zum Segmentanfang der RD addieren
  326.          mov  ds,ax              ;nach DS bertragen
  327.          xor  si,si              ;Offsetadresse ist 0
  328.          mov  ax,bx              ;Anzahl zu lesende Sektoren nach AX
  329.          cmp  ax,128             ;noch mehr als 128 Sektoren lesen
  330.          jbe  move_2             ;NEIN --> alle Sektoren lesen
  331.          mov  ax,128             ;JA --> 128 Sektoren (64 KB) lesen
  332. move_2:  sub  bx,ax              ;Anzahl der gelesenen Sektoren abziehen
  333.          add  dx,ax              ;auf n„chsten zu lesenden Sek. addieren
  334.          mov  ch,al              ;Anzahl zu lesende Sektoren * 256 Words
  335.          xor  cl,cl              ;Lo-Byte des Word-Z„hler auf 0 setzen
  336.          or   bp,bp              ;soll gelesen werden?
  337.          jne  move_3             ;NEIN --> MOVE_3
  338.          mov  ax,es              ;ES in AX merken
  339.          push ds                 ;DS auf dem Stack merken
  340.          pop  es                 ;als ES zurckholen
  341.          mov  ds,ax              ;ES und DS sind damit vertauscht
  342.          xchg si,di              ;und SI und DI vertauschen
  343. move_3:  rep  movsw              ;Daten in den DOS-Puffer kopieren
  344.          or   bp,bp              ;soll gelesen werden?
  345.          jne  move_1             ;NEIN --> evtl. weitere Sek. kopieren
  346.          mov  ax,es              ;ES in AX merken
  347.          push ds                 ;DS auf dem Stack merken
  348.          pop  es                 ;als ES zurckholen
  349.          mov  ds,ax              ;ES und DS sind damit vertauscht
  350.          xchg si,di              ;und SI und DI wieder zurcktauschen
  351.          jmp  short move_1       ;evtl. weitere Sektoren kopieren
  352.                                                                         
  353. move_e:  xor  ax,ax              ;alles o.k.
  354.          ret                     ;zurck zum Aufrufer
  355.                                                                         
  356. move     endp
  357.                                                                         
  358. ;-- ab hier beginnt die eigentliche RAMDisk ----------------------------
  359.                                                                         
  360.          org ($-erst_b) + 16 - (($-erst_b) mod 16)
  361.                                                                         
  362. ramdisk  equ this byte
  363.                                                                         
  364. initm    db "**** 160 KB RAMDISK als Laufwerk "
  365. im_ger   db "?"
  366.      db ": installiert. (c) 1987,1991 by MICHAEL TISCHER$",13,10,10
  367.                                                                         
  368. ;-----------------------------------------------------------------------
  369.                                                                         
  370. code     ends
  371.          end
  372.